﻿using System;
using System.Windows.Controls;
using System.Windows.Media;
using Geotools.Geometries;
using AzukiMap.Renderer;
using AzukiMap.Map;
using System.Windows.Media.Imaging;
using AzukiMap.Request;
using AzukiMap.Layer;
using AzukiMap.DataSource;
using System.Windows.Threading;
using AzukiMap;
using System.Collections.Generic;

namespace AzukiMapUI
{
    public class DrawingTest
    {
        MapControl _mapControl;
        MapCanvas _commonCanvas;
        MapCanvas _wmsCanvas;
        MapCanvas _kaMapCanvas;
        MapCanvas _aeroCanvas;
        MapCanvas _rasterCanvas;
        MapCanvas _veCanvas;
        MapCanvas _veCanvas2;
        VectorRendererSL _renderer;
        GeometryFactory _geoFactory;
        VectorStyle _style;
        VectorLayer _gyouseiLayer;
        WMSLayer _wmsLayer;
        WMSLayer _aeroLayer;
        RasterLayer _rasterLayer;

        //public DrawingTest(MapCanvas mapCanvas)
        public DrawingTest(MapControl mapControl)
        {
            _mapControl = mapControl;
            _mapControl.Srid = 4326;
            _commonCanvas = _mapControl.CreateMapCanvas();
            _commonCanvas.Opacity = 0.25;
            _wmsCanvas = _mapControl.CreateMapCanvas();
            _wmsCanvas.Opacity = 0.25;
            _rasterCanvas = _mapControl.CreateMapCanvas();
            _kaMapCanvas = _mapControl.CreateMapCanvas();
            _veCanvas = _mapControl.CreateMapCanvas();
            _veCanvas2 = _mapControl.CreateMapCanvas();
            _renderer = new VectorRendererSL(_commonCanvas);
            _geoFactory = new GeometryFactory();
            _style = new VectorStyle();
            _aeroCanvas = _mapControl.CreateMapCanvas();
            //SetWMSTest();
            //SetRasterImage();
            //SetOrthoPhoto();
            SetKaMapLayer();
            SetVE();
            SetVE2();
            //SetGyousei();
        }
    
        public void DrawSimplePolygon()
        {
            GTGeometry polygon = _geoFactory.CreateFromWKT("POLYGON((100 100, 500 100, 500 400, 100 400, 100 100))");
            _renderer.DrawGeometry(1, polygon, _style);
        }

        public void DrawPolygonWithInterior()
        {
            _style.Fill = new SolidColorBrush(Colors.White);
            GTGeometry polygon = _geoFactory.CreateFromWKT(
                "POLYGON((200 200, 400 200, 400 400, 200 400, 200 200),(250 250, 350 250, 350 350, 250 350, 250 250))");
            _renderer.DrawGeometry(2, polygon, _style);
        }

        public void DrawMultiPolygon()
        {
            _style.Fill = new SolidColorBrush(Colors.Yellow);
            GTGeometry polygon = _geoFactory.CreateFromWKT(
                "MULTIPOLYGON(((200 200, 250 200, 250 250, 200 250, 200 200),(200 200, 350 250, 350 350, 250 350, 200 200)))");
            _renderer.DrawGeometry(3, polygon, _style);
        }

        public void DrawPointAsCircle()
        {
            _style.Fill = new SolidColorBrush(Colors.Green);
            _style.PointHeight = 10;
            _style.PointWidth = 10;
            _style.PointType = PointDrawingType.Circle;
            string pointStr = CreateRandomPointsStr(1000, 800, 1);
            GTGeometry point = _geoFactory.CreateFromWKT( "POINT(" + pointStr + ")");
            _renderer.DrawGeometry(4, point, _style);
        }

        public void DrawMultiPointAsCircle()
        {
            _style.Fill = new SolidColorBrush(Colors.Blue);
            _style.PointHeight = 10;
            _style.PointWidth = 10;
            _style.PointType = PointDrawingType.Circle;
            string pointStr = CreateRandomPointsStr(1000, 800, 10);
            GTGeometry points = _geoFactory.CreateFromWKT( "MULTIPOINT(" + pointStr +")");
            _renderer.DrawGeometry(5, points, _style);
        }

        public void DrawPointAsRect()
        {
            _style.Fill = new SolidColorBrush(Colors.Green);
            _style.PointHeight = 10;
            _style.PointWidth = 10;
            _style.PointType = PointDrawingType.Rect;
            string pointStr = CreateRandomPointsStr(1000, 800, 1);
            GTGeometry point = _geoFactory.CreateFromWKT( "POINT(" + pointStr + ")");
            _renderer.DrawGeometry(4, point, _style);
        }

        public void DrawMultiPointAsRect()
        {
            _style.Fill = new SolidColorBrush(Colors.Blue);
            _style.PointHeight = 10;
            _style.PointWidth = 10;
            _style.PointType = PointDrawingType.Rect;
            string pointStr = CreateRandomPointsStr(1000, 800, 10);
            GTGeometry points = _geoFactory.CreateFromWKT( "MULTIPOINT(" + pointStr +")");
            _renderer.DrawGeometry(5, points, _style);
        }

        public void DrawPointAsImage(ImageSource imgSource)
        {
            Image pointImage = new Image();
            /*
            pointImage.Source = imgSource;
             */
            Uri imageUri = new Uri("http://www.coffee-bean-shop.co.uk/Images/small_bean_1.jpg");
            BitmapImage bitmap = new BitmapImage(imageUri);
            pointImage.Source = bitmap;

            _style.Fill = new SolidColorBrush(Colors.Green);
            _style.PointHeight = 10;
            _style.PointWidth = 10;
            _style.PointType = PointDrawingType.Bitmap;
            _style.PointImage = pointImage;

            string pointStr = CreateRandomPointsStr(1000, 800, 1);
            GTGeometry point = _geoFactory.CreateFromWKT( "POINT(" + pointStr + ")");
            _renderer.DrawGeometry(4, point, _style);
        }

        public void DrawMultiPointAsImage(ImageSource imgSource)
        {
            Image pointImage = new Image();
            pointImage.Source = imgSource;
            /*
            Image pointImage = new Image();
            Uri imageUri = new Uri("bean_small.png");
            BitmapImage bitmap = new BitmapImage(imageUri);
            pointImage.Source = bitmap;
             */

            _style.Fill = new SolidColorBrush(Colors.Blue);
            _style.PointHeight = 10;
            _style.PointWidth = 10;
            _style.PointType = PointDrawingType.Bitmap;
            _style.PointImage = pointImage;

            string pointStr = CreateRandomPointsStr(1000, 800, 10);
            GTGeometry points = _geoFactory.CreateFromWKT( "MULTIPOINT(" + pointStr +")");
            _renderer.DrawGeometry(5, points, _style);
        }

        public void DrawLineString()
        {
            _style.Stroke = new SolidColorBrush(Colors.Cyan);
            _style.StrokeThickness = 0.5;
            string pointStr = CreateRandomPointsStr(1000, 800, 100);
            GTGeometry line = _geoFactory.CreateFromWKT( "LINESTRING(" + pointStr +")");
            _renderer.DrawGeometry(6, line, _style);
        }

        public void DrawMultiLineString()
        {
            _style.Stroke = new SolidColorBrush(Colors.Orange);
            _style.StrokeThickness = 2.5;
            string pointStr1 = CreateRandomPointsStr(1000, 800, 100);
            string pointStr2 = CreateRandomPointsStr(1000, 800, 100);
            string pointStr3 = CreateRandomPointsStr(1000, 800, 100);
            GTGeometry line = _geoFactory.CreateFromWKT(
                "MULTILINESTRING((" + pointStr1 + "),(" + pointStr2 +"),(" + pointStr3 +"))");
            _renderer.DrawGeometry(6, line, _style);
        }

        public void DrawChiyodaku()
        {
            _style.Fill = new SolidColorBrush(Colors.Green);
            _style.Stroke = new SolidColorBrush(Colors.Orange);
            _style.StrokeThickness = 0.5;
            GTGeometry chiyodaPoly = _geoFactory.CreateFromWKT(
                "MULTIPOLYGON(((139.758018 35.668697,139.753768 35.670063,139.75343 35.670138,139.752955 35.67018,139.751631 35.670413,139.751031 35.670596,139.750781 35.670646,139.749979 35.670824,139.749505 35.670824,139.749194 35.670779,139.748165 35.669898,139.747803 35.669618,139.747672 35.669611,139.747485 35.669656,139.74723 35.66989,139.746985 35.670058,139.746956 35.670503,139.746769 35.670508,139.746643 35.670471,139.746189 35.67052,139.745342 35.670669,139.745281 35.671007,139.743661 35.671251,139.743473 35.671313,139.743034 35.671543,139.740013 35.673384,139.73904 35.674032,139.73876 35.674587,139.738614 35.675117,139.738294 35.675821,139.737541 35.67686,139.737456 35.677195,139.737231 35.678006,139.736769 35.678861,139.736366 35.678803,139.735247 35.678709,139.73443 35.678756,139.734132 35.678795,139.734028 35.678803,139.733796 35.678887,139.7334 35.679222,139.733169 35.679537,139.733015 35.679909,139.73292 35.680229,139.732807 35.680474,139.732606 35.680642,139.731617 35.681334,139.731499 35.681491,139.731031 35.682288,139.730664 35.683098,139.730456 35.683638,139.730261 35.684529,139.730172 35.684671,139.729994 35.685567,139.730056 35.685724,139.730163 35.685905,139.73026 35.68629,139.730291 35.686758,139.730673 35.687552,139.730807 35.688173,139.73086 35.688338,139.730984 35.688556,139.731162 35.689122,139.731339 35.68935,139.73157 35.689578,139.732663 35.690097,139.73412 35.691039,139.736297 35.6922,139.736693 35.692535,139.737736 35.693421,139.738833 35.694745,139.741534 35.698341,139.743585 35.700656,139.744118 35.701274,139.743677 35.701617,139.744097 35.702,139.74447 35.702304,139.744571 35.702314,139.744707 35.702231,139.745394 35.702598,139.74585 35.702907,139.745998 35.703006,139.746704 35.703175,139.74677 35.703124,139.747978 35.703161,139.749031 35.703126,139.749329 35.703084,139.749713 35.703036,139.749929 35.702943,139.750335 35.70277,139.750654 35.702693,139.75084 35.702651,139.751298 35.702624,139.75283 35.702505,139.754144 35.702365,139.755366 35.702101,139.757174 35.701719,139.759066 35.701635,139.760029 35.701652,139.760929 35.701602,139.761779 35.701485,139.762404 35.701093,139.763016 35.700502,139.763666 35.700252,139.764816 35.69991,139.765328 35.699794,139.766019 35.699632,139.767126 35.700109,139.767493 35.700031,139.768269 35.6997,139.768506 35.70013,139.767706 35.700743,139.767866 35.700968,139.767445 35.701162,139.767297 35.70101,139.767028 35.701294,139.766829 35.701493,139.766397 35.701776,139.766782 35.702646,139.767834 35.702596,139.767874 35.702736,139.768099 35.70275,139.76806 35.703461,139.769884 35.703356,139.770085 35.704158,139.770144 35.705353,139.773044 35.705096,139.772786 35.70313,139.773648 35.703036,139.773168 35.701875,139.776643 35.700606,139.78039 35.700294,139.779963 35.698078,139.782657 35.697857,139.78255 35.696559,139.782532 35.696214,139.782062 35.696253,139.781982 35.695246,139.782586 35.694714,139.781866 35.694178,139.780232 35.692974,139.779983 35.693158,139.778645 35.692198,139.777697 35.691765,139.774453 35.690612,139.773216 35.69017,139.771099 35.689396,139.770428 35.689103,139.769953 35.689037,139.769279 35.688845,139.768479 35.688512,139.768191 35.688445,139.768279 35.68822,139.768554 35.687853,139.769066 35.687445,139.769879 35.686537,139.770066 35.686362,139.770354 35.685954,139.770591 35.685112,139.770741 35.684729,139.770991 35.684346,139.771016 35.684012,139.770466 35.682796,139.770266 35.682437,139.770004 35.681804,139.769066 35.680596,139.767804 35.678596,139.767116 35.677338,139.766541 35.676413,139.764942 35.674305,139.764254 35.673338,139.764079 35.673163,139.763717 35.672963,139.763454 35.672871,139.762492 35.672696,139.761867 35.672546,139.761367 35.672346,139.761129 35.672097,139.760967 35.67183,139.760792 35.671763,139.76043 35.671697,139.759635 35.67168,139.759455 35.67123,139.758942 35.67028,139.758792 35.669905,139.758555 35.669688,139.758043 35.668922,139.758018 35.668697)))"
            );
            _renderer.DrawGeometry(13101, chiyodaPoly, _style);

        }

        public void SetGyousei()
        {
            PostGisTable pgTable = new PostGisTable("gyousei", DataTypes.MultiPolygon, 4326, CoordinationUnits.DEGREES);
            pgTable.DbName = "datapack";
            pgTable.GeometryColumn = "the_geom";
            pgTable.TableName = "gyousei";
            pgTable.TableSchema = "public";
            pgTable.TableCatalog = "";

            _gyouseiLayer = new PostGisLayer(pgTable, _commonCanvas, "gyousei");

            VectorStyle style = new VectorStyle();
            style.Fill = null;
            style.Opacity = 0.5;
            style.StrokeThickness = 4;
            style.StrokeDashOffset = 5;
            style.Stroke = new SolidColorBrush(Colors.Black);

            _gyouseiLayer.DefaultStyle = style;
            _gyouseiLayer.MaxScale = 1000000;

            _mapControl.AddLayer(_gyouseiLayer);

        }

        public void DrawGyousei()
        {
            _gyouseiLayer.Draw();
        }

        public void SetWMSTest()
        {
            WMSProvider wms = new WMSProvider("chishitsu", DataTypes.Raster, 4326, CoordinationUnits.DEGREES);
            //wms.RequestUri = "http://columbo.nrlssc.navy.mil/ogcwms/servlet/WMSServlet/Japan_Landslide_Maps.wms";
            wms.RequestUri = "http://geodata1.geogrid.org/mapserv/g1000k/g1000kj";
            wms.Format = RasterImageFormat.PNG;
            wms.Transparent = true;
            wms.Layers.Add("g1000kj");
            //wms.Name = "WMS test";
            wms.Version = WMSVersion.V1_1_1;

            GeometryUtil geoUtil = new GeometryUtil();
            //wms.MaxExtent = new GTEnvelope(122.943, 20.4586, 153.99, 45.5565);
            wms.MaxExtent = geoUtil.CreateExtentPolygon(122.943, 45.5565, 122.943, 20.4586, 153.99, 20.4586, 153.99, 45.5565);
            
            //wms.Srid = 4326;

            _wmsLayer = new WMSLayer(wms, _wmsCanvas, "WMS test");
            _wmsLayer.MaxExtent = wms.MaxExtent;
            _wmsLayer.MinScale = 4989.02848429637; 

            _mapControl.AddLayer(_wmsLayer);
        }

        public void SetKaMapLayer()
        {
            List<string> uris = new List<string>();
            uris.Add("http://auigt1.eoc.jaxa.jp/php/tile.php");
            uris.Add("http://auigt2.eoc.jaxa.jp/php/tile.php");
            uris.Add("http://auigt3.eoc.jaxa.jp/php/tile.php");
            uris.Add("http://auigt4.eoc.jaxa.jp/php/tile.php");

            List<double> scales = new List<double>();
            scales.Add(179420290);
            scales.Add(89710145);
            scales.Add(44855072);
            scales.Add(22427536);
            scales.Add(11213768);
            scales.Add(5606884);
            scales.Add(2803442);
            scales.Add(1401721);
            scales.Add(700860);
            scales.Add(350430);
            scales.Add(175215);
            scales.Add(87607);
            scales.Add(43803);
            /*
            scales.Add(11665);
             */

            List<string> groups = new List<string>();
            //groups.Add("satelite");
            groups.Add("map");

            KaMapTiles kmSource = new KaMapTiles("Dd", uris, 4326, CoordinationUnits.DEGREES, 316, 316, scales, 72);
            kmSource.GroupNames = groups;

            KaMapLayer kaMapLayer = new KaMapLayer(kmSource, _kaMapCanvas, "auig", null);

            _mapControl.AddLayer(kaMapLayer);
            
        }

        public void SetVE()
        {
            VirtualEarthTiles veSource = new VirtualEarthTiles("ve");
            veSource.TileType = VirtualEarthLayerType.HYBRID;
            VirtualEarthLayer veLayer = new VirtualEarthLayer(veSource, _veCanvas, "ve");
            _veCanvas.Opacity = 0.25;
            _mapControl.AddLayer(veLayer);
        }

        public void SetVE2()
        {
            /*
            VirtualEarthTiles veSource2 = new VirtualEarthTiles("ve2");
            veSource2.TileType = VirtualEarthLayerType.TRAFFIC;
            VirtualEarthLayer veLayer = new VirtualEarthLayer(veSource2, _veCanvas2, "ve");
            _veCanvas.Opacity = 0.25;
            _mapControl.AddLayer(veLayer);
             */
        }

        public void SetOrthoPhoto()
        {
            WMSProvider wms = new WMSProvider("Ortho Photo", DataTypes.Raster, 4612, CoordinationUnits.DEGREES);
            wms.RequestUri = "http://orthophoto.mlit.go.jp:8888/wms/service/wmsRasterTileMap";
            wms.Format = RasterImageFormat.JPEG;
            wms.Transparent = true;
            wms.Layers.Add("ORTHO");
            wms.BBoxLatLonOrder = LatLonOrder.LAT_LON;
            wms.Version = WMSVersion.V1_3_0;

            GeometryUtil geoUtil = new GeometryUtil();
            //wms.MaxExtent = new GTEnvelope(122.943, 20.4586, 153.99, 45.5565);
            wms.MaxExtent = geoUtil.CreateExtentPolygon(125, 50, 125, 20, 150, 20, 150, 50);
            
            _aeroLayer = new WMSLayer(wms, _aeroCanvas, "WMS test");
            _aeroLayer.MaxExtent = wms.MaxExtent;
            _aeroLayer.MaxScale = 25000; 

            _mapControl.AddLayer(_aeroLayer);
        }

        public void SetRasterImage()
        {
            Uri rSource = new Uri("http://lsweb1.ess.bosai.go.jp/jisuberi/GoogleEarth/shiroumadake.jpg");
            GeometryUtil geoUtil = new GeometryUtil();
            GTPolygon rExtent = geoUtil.CreateExtentPolygon(137.7469,36.8364,137.7469,36.66975,137.99689,36.66975,137.99689,36.8364);
            //GTPolygon rExtent = geoUtil.CreateExtentPolygon(132,34,132,33,132.1,33,132.1,34);
            RasterImage raster = new RasterImage(rSource, rExtent, 2640,2186, 72, "shirouma", DataTypes.Raster, 4326, CoordinationUnits.DEGREES);

            _rasterLayer = new RasterLayer(raster, _rasterCanvas, "shirouma");
            _rasterLayer.MaxScale = 1000000;

            _mapControl.AddLayer(_rasterLayer);
        }

        public void RemoveAll()
        {
            _commonCanvas.Children.Clear();
        }

        string CreateRandomPointsStr(double width, double height, int count)
        {
            Random rand = new Random();
            string pointStr = "";
            for (int i = 0; i < count; i++)
            {
                double x = rand.NextDouble() * width;
                double y = rand.NextDouble() * height;
                pointStr += x.ToString() + " " + y.ToString();
                if (i + 1 < count)
                {
                    pointStr += ",";
                }
            }
            return pointStr;
        }

    }


}
